using System;
using System.Collections.Generic; 
using UnityEngine;

namespace XFGameFramework.Localization
{

    /// <summary>
    /// 多语言系统业务逻辑
    /// </summary>
    public class LocalizationManager
    {
         
        #region 常量

        private const string LOCALIZATION_LANGUAGE_KEY = "XFGameFramework.Localization.LOCALIZATION_LANGUAGE_KEY";

        #endregion
         
        #region 字段

        private static List<MultiLanguageConfigs> _configs = new List<MultiLanguageConfigs>();

        /// <summary>
        /// 所有的语言,key:语言类型 value:显示名称
        /// </summary>
        [Tooltip("所有的语言,key:语言类型 value:显示名称")] 
        public static Dictionary<SystemLanguage, string> Languages = new Dictionary<SystemLanguage, string>();

        private static SystemLanguage language = SystemLanguage.Unknown;

#if UNITY_EDITOR
        // 编辑器模式下使用的
        private static List<MultiLanguageConfigs> _configs_editor = new List<MultiLanguageConfigs>();
#endif

        #endregion

        #region 属性

        /// <summary>
        /// 当前的语言(持久化保存)
        /// </summary>
        public static SystemLanguage Language
        {
            get
            {
                if (language == SystemLanguage.Unknown)
                {
                    int language_value = PlayerPrefs.GetInt(LOCALIZATION_LANGUAGE_KEY, -1);

                    if (language_value != -1)
                    {
                        language = (SystemLanguage)language_value;
                    }
                    else
                    {
                        for (int i = 0; i < Configs.Count; i++)
                        {
                            if (Configs[i] == null)
                                continue;
                            for (int j = 0; j < Configs[i].Languages.Count; j++)
                            {
                                if (Configs[i].Languages[j].language == Application.systemLanguage)
                                {
                                    language = Application.systemLanguage;
                                    break;
                                }
                            }
                        }

                        // 判断是否为中文(因为中文有3种，比较特殊)
                        if (language == SystemLanguage.Unknown && IsChinese(Application.systemLanguage))
                        {

                            for (int i = 0; i < Configs.Count; i++)
                            {
                                if (Configs[i] == null)
                                    continue;
                                if (Configs[i].GetLanguageConfigData(SystemLanguage.Chinese) != null)
                                    language = SystemLanguage.Chinese;
                                if (Configs[i].GetLanguageConfigData(SystemLanguage.ChineseSimplified) != null)
                                    language = SystemLanguage.ChineseSimplified;
                                if (Configs[i].GetLanguageConfigData(SystemLanguage.ChineseTraditional) != null)
                                    language = SystemLanguage.ChineseTraditional;
                            }
                        }

                        // 判断是否有英文，优先使用英文
                        if (language == SystemLanguage.Unknown)
                        {
                            for (int i = 0; i < Configs.Count; i++)
                            {
                                if (Configs[i] == null)
                                    continue;
                                if (Configs[i].GetLanguageConfigData(SystemLanguage.English) != null)
                                {
                                    language = SystemLanguage.English;
                                    break;
                                }
                            }
                        }

                        // 随便找一个
                        if (language == SystemLanguage.Unknown) 
                        {
                            for (int i = 0; i < Configs.Count; i++)
                            {
                                if (Configs[i] == null)
                                    continue;

                                foreach (var item in Configs[i].Languages)
                                {
                                    if (item == null) continue;
                                    language = item.language;
                                    break;
                                }
                            }
                        }

                    }
                }

                return language;
            }
            set
            {
                if (language == value)
                    return;

                language = value;
                EventManager.TriggerEvent(LocalizationEventConst.ON_LANGUAGE_VALUE_CHANGE);
                PlayerPrefs.SetInt(LOCALIZATION_LANGUAGE_KEY, value == SystemLanguage.Unknown ? -1: (int)value);
                PlayerPrefs.Save();

            }

        }

        /// <summary>
        /// 所有配置
        /// </summary>
        public static List<MultiLanguageConfigs> Configs
        {
            get
            {

#if UNITY_EDITOR

                bool isPlaying = Application.isPlaying;

                if (!isPlaying)
                {
                    if (_configs_editor.Count == 0)
                    {
                        // 编辑器模式 非运行状态 
                        string[] guids = UnityEditor.AssetDatabase.FindAssets(string.Format("t:{0}", typeof(MultiLanguageConfigs)));

                        foreach (var item in guids)
                        {
                            string asset_path = UnityEditor.AssetDatabase.GUIDToAssetPath(item);
                            MultiLanguageConfigs config = UnityEditor.AssetDatabase.LoadAssetAtPath<MultiLanguageConfigs>(asset_path);
                            if (config == null) continue;
                            _configs_editor.Add(config);
                        }
                    }

                    return _configs_editor;
                }
#endif

                return _configs;
            }
        }

        #endregion
         
        /// <summary>
        /// 添加配置
        /// </summary>
        /// <param name="config">配置对象</param>
        /// <exception cref="Exception"></exception>
        public static void AddConfig(MultiLanguageConfigs config)
        {
            if (config == null) return;

            if (Configs.Contains(config))
                return;

            foreach (var item in Configs)
            {
                foreach (var language in item.Languages)
                {
                    if (language == null) continue;

                    LanguageConfig languageConfig = config.GetLanguageConfigData(language.language);
                    if (languageConfig == null) continue;

                    foreach (var info in language.languagesInfo)
                    {
                        if (languageConfig.GetLanguageInfo(info.id) != null)
                        {
                            throw new Exception(string.Format("配置:{0} 和 配置:{1} 语言:{2} id:{3} 重复!", item.name, config.name, language.language, info.id));
                        }
                    }
                    break;
                }
            }

            Configs.Add(config);
            RefreshAllLanguages();
        }


        /// <summary>
        /// 移除配置
        /// </summary>
        /// <param name="name">配置名称</param>
        public static void RemoveConfig(string name) 
        {
            MultiLanguageConfigs configs = GetConfig(name);
            if (configs == null) return;
            RemoveConfig(configs);
        }

        /// <summary>
        /// 移除配置
        /// </summary>
        /// <param name="config">配置对象</param>
        public static void RemoveConfig(MultiLanguageConfigs config)
        {
            if (!Configs.Contains(config))
                return;
            Configs.Remove(config);

            RefreshAllLanguages();
        }

        /// <summary>
        /// 查询配置
        /// </summary>
        /// <param name="name">配置文件名称</param>
        /// <returns></returns>
        public static MultiLanguageConfigs GetConfig(string name)
        {
            foreach (var item in Configs)
            {
                if(item == null) 
                    continue;
                if(item.name == name) 
                    return item;
            }

            return null;
        }

        /// <summary>
        /// 查询多语言信息
        /// </summary>
        /// <param name="id">唯一标识</param>
        /// <returns></returns>
        public static LanguageInfo GetLanguageInfo(int id)
        {
            foreach (var config in Configs)
            {
                LanguageConfig languageConfig = config.GetLanguageConfigData(Language);
                if (languageConfig == null) continue;
                LanguageInfo info = languageConfig.GetLanguageInfo(id);
                if (info != null)
                    return info;
            }

            // 说明没查到，随便返回一个语言
            foreach (var config in Configs)
            {
                foreach (var language in config.Languages)
                {
                    if (language == null) continue;

                    LanguageInfo info = language.GetLanguageInfo(id);
                    if (info != null)
                        return info;

                    break;
                }
            }

            return null;
        }


        private static bool IsChinese(SystemLanguage language)
        {

            bool chinese = language == SystemLanguage.Chinese
                || language == SystemLanguage.ChineseSimplified
                || language == SystemLanguage.ChineseTraditional;

            return chinese;
        }

        private static void RefreshAllLanguages()
        {
            Languages.Clear();

            foreach (var item in Configs)
            {
                foreach (var language in item.Languages)
                {
                    if (Languages.ContainsKey(language.language))
                        continue;
                    Languages.Add(language.language, string.IsNullOrEmpty(language.displayName) ? language.language.ToString() : language.displayName);
                }
            }

        }

    }
}

